“aws:PrincipalOrgID”はサービスプリンシパルでは使えないので注意しよう
こんにちはオンジー(@onzuka_muscle)です!
AWSグローバル条件コンテキストキーの中に"aws:PrincipalOrgID"というキーがあります。
このキーを使用して、リクエスト元のプリンシパルが属する AWS Organizations の組織の識別子と、ポリシーで指定された識別子を比較します。
AWS Organizations を利用している環境でクロスアカウントなアクセス制御に使おうとした際に少しハマったので記事として残しておきます。
はじめにまとめ
最初に結論ですが「"aws:PrincipalOrgID"はサービスプリンシパルでは使えない」です。(タイトルまんま)
それはなぜかと言うと
"aws:PrincipalOrgID" は Principal が組織のメンバーの場合のみリクエストコンテキストに含まれるが、Service の場合は "aws:PrincipalOrg" はリクエストコンテキストに含まれないためです。
具体例
上記の表現だけでは伝わりづらいので具体例を示します。
僕が実際に失敗した構成は下記のような構成です。
SQSのリソースベースポリシーのCondition句で"aws:PrincipalOrgID"を用いることで、組織内の別アカウントにあるSNSからのメッセージ送信を許可しようとしました。
しかし、これは正常に動作しません。
なぜならまとめに書いてあるように、サービスプリンシパル(図ではSNS)からのリクエストの中に"aws:PrincipalOrgID"が含まれていないからです。
ちなみにこのポリシーについて、どのような動作になったかと言うとSNSからSQSにメッセージは送信できませんでした。Allowするための条件(Conditon)が正常に動作していないので当然そうなります。
アクセスを許可するためにはSNSトピックのARNを個別に指定する必要があります。(最後に参考ドキュメントを載せています。)
またやりたかった制御ではないですが、このポリシーは、Organizations 管理下のアカウントから AWS CLI などで直接 SQS にメッセージを送信することを許可しています。
AWS CLIを使う場合、プリンシパルがサービスプリンシパルではなく組織のメンバーであるからです。もしそのようなユースケースで用いるなら正常に動作するポリシーと言えますね。
おわり
実を言うと"aws:PrincipalOrgID"のドキュメントには下記のようにちゃんと書かれています。
可用性 – このキーは、プリンシパルが組織のメンバーである場合にのみリクエストコンテキストに含まれます。
僕のようにあまり注意深くここの意味を考えずにサービスプリンシパルでも使えるでしょ〜と思ってハマる人の助けに少しでもなれば嬉しいです。